#ifndef WEBSOCKET_H
#define WEBSOCKET_H

#include "socket.h"

/**
 * @brief The WebSocket class inherits the Socket class
 */
class WebSocket : public Socket
{
    Q_OBJECT
private:
    struct Frame{
        char fin:1;
        char rsv1:1;
        char rsv2:1;
        char rsv3:1;
        char opcode:4;
        char mask:1;
        int length;
        char maskKey[4];
        int dataIndex;
    };

public:
    WebSocket(QObject *parent = 0);

    /**
     * @brief write writes data including the mandatory websocket header. It is also possible to encode the data.
     * @param data is the data that forms the payload
     * @return the size of the data that has been sent
     */
    qint64 write(const QByteArray& data);

public Q_SLOTS:
    /**
     * @brief processIncomingData is an overrided method that decodes the data when they comes from the web browser.
     */
    void processIncomingData();

private:
    /**
     * @brief computeFrame is a static method that fills a Frame structure based on the header included in the whole frame 'frame'
     * @param frame is the whole received message
     * @return
     */
    static Frame computeFrame(QByteArray frame);

    /**
     * @brief computeAcceptKey computes the AcceptKey based on the key 'key', look at the websocket specs.
     * @param key is the key from which the function computes the AcceptKey
     * @return the AcceptKey to send back to the browser
     */
    static QString computeAcceptKey(QString key);

Q_SIGNALS:
    /**
     * @brief handshakeSuccess is the signal emitted when the handshake has succeded
     */
    void handshakeSuccess();

    void handshakeFailed();

    /**
     * @brief onClosing is the signal emitted when the websocket is about to close. It sends the closing frame and emits the signal right away.
     */
    void onClosing();

private:
    /**
     * @brief The State enum is an enum defining the different states of the socket.
     */
    enum State{
        Handshake,
        Opened,
        Closed
    };



    QByteArray v_dataStream;

    // Is the current socket state
    State v_state;
};

#endif // WEBSOCKET_H
